/*
 * This file is part of the <a href="http://code.google.com/p/pux">PUX Framework</a>
 *
 * Copyright 2008 by <a href="mailto:jfendler@polytechnic.edu.na">Jens Fendler</a>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package de.teamskill.pux.library.xml;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.net.URL;

import org.jdom.Document;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import de.teamskill.pux.engine.InputPort;
import de.teamskill.pux.engine.AbstractNode;
import de.teamskill.pux.engine.OutputPort;

/**
 * LoadDocumentNode
 * 
 * @author <a href="mailto:jfendler@polytechnic.edu.na">Jens Fendler</a>
 * 
 */
public class LoadDocumentNode extends AbstractNode {

	/**
	 * OUT_DOCUMENT
	 */
	public static final String OUT_DOCUMENT = "DOCUMENT";

	/**
	 * CONFIG_SOURCE
	 */
	public static final String CONFIG_SOURCE = "source";

	/**
	 * CONFIG_VALIDATE
	 */
	public static final String CONFIG_VALIDATE = "validate";

	/**
	 * source
	 */
	private InputPort source;

	/**
	 * validate
	 */
	private InputPort validate;

	/**
	 * document
	 */
	private OutputPort document;

	/**
	 * LoadDocumentNode Constructor
	 * 
	 */
	public LoadDocumentNode() {
		this("LOADXML" + nr++, false);
	}

	/**
	 * LoadDocumentNode Constructor
	 * 
	 * @param nodeName
	 * @param continuous
	 */
	public LoadDocumentNode(String nodeName, boolean continuous) {
		super(nodeName, continuous);
	}

	/**
	 * @see de.teamskill.pux.engine.AbstractNode#compute()
	 */
	public void compute() {
		boolean val = (Boolean) validate.fetchData();
		Object xmlSource = source.fetchData();
		Document doc = null;
		SAXBuilder builder = new SAXBuilder(val);
		try {
			if (xmlSource instanceof String) {
				doc = builder.build((String) xmlSource);
				document.pushData(doc);
			} else if (xmlSource instanceof File) {
				doc = builder.build((File) xmlSource);
				document.pushData(doc);
			} else if (xmlSource instanceof Reader) {
				doc = builder.build((Reader) xmlSource);
				document.pushData(doc);
				((Reader) xmlSource).close();
			} else if (xmlSource instanceof InputStream) {
				doc = builder.build((InputStream) xmlSource);
				document.pushData(doc);
				((InputStream) xmlSource).close();
			} else if (xmlSource instanceof URL) {
				doc = builder.build((URL) xmlSource);
				document.pushData(doc);
			}
		} catch (JDOMException e) {
			LOG_NODE.severe(getNodeName() + " failed to parse DOM tree: " + e.getLocalizedMessage());
		} catch (IOException e) {
			LOG_NODE.severe(getNodeName() + " failed to read XML data: " + e.getLocalizedMessage());
		}
	}

	/**
	 * @see de.teamskill.pux.engine.AbstractNode#createPorts()
	 */
	protected void createPorts() {
		document = addOutputPort(new OutputPort(OUT_DOCUMENT, this, Document.class));
		source = addConfigurationPort(CONFIG_SOURCE, Object.class);
		validate = addConfigurationPort(CONFIG_VALIDATE, Boolean.class, new Boolean(false));
	}

	/**
	 * JavaBean-style getter-method for source
	 * 
	 * @return the source
	 */
	public InputPort getSource() {
		return source;
	}

	/**
	 * /** JavaBean-style setter-method for source
	 * 
	 * @param source
	 *            the source to set
	 */
	public void setSource(InputPort source) {
		this.source = source;
	}

	/**
	 * JavaBean-style getter-method for validate
	 * 
	 * @return the validate
	 */
	public InputPort getValidate() {
		return validate;
	}

	/**
	 * /** JavaBean-style setter-method for validate
	 * 
	 * @param validate
	 *            the validate to set
	 */
	public void setValidate(InputPort validate) {
		this.validate = validate;
	}

	/**
	 * JavaBean-style getter-method for document
	 * 
	 * @return the document
	 */
	public OutputPort getDocument() {
		return document;
	}

	/**
	 * /** JavaBean-style setter-method for document
	 * 
	 * @param document
	 *            the document to set
	 */
	public void setDocument(OutputPort document) {
		this.document = document;
	}

}
